<?php
namespace app\controller\admin;

use app\model\CouponModel;
use app\model\UserCouponModel;
use support\Request;
use app\exception\BusinessException;
use hg\apidoc\annotation as Apidoc;

/**
 * @Apidoc\Title("优惠券管理")
 * @Apidoc\Group("admin")
 */
class CouponController
{
    /**
     * @Apidoc\Title("获取优惠券列表")
     * @Apidoc\Method("GET")
     * @Apidoc\Url("/admin/coupon/list")
     * @Apidoc\Param("page", type="int", default=1, desc="页码")
     * @Apidoc\Param("page_size", type="int", default=15, desc="每页数量")
     * @Apidoc\Param("name", type="string", desc="优惠券名称")
     * @Apidoc\Param("type", type="int", desc="优惠券类型")
     * @Apidoc\Param("status", type="int", desc="状态")
     * @Apidoc\Param("start_time", type="string", desc="开始时间")
     * @Apidoc\Param("end_time", type="string", desc="结束时间")
     */
    public function list(Request $request)
    {
        $params = $request->all();
        $page = $request->get('page', 1);
        $pageSize = $request->get('page_size', 15);
        
        $query = CouponModel::query();
        
        // 搜索条件
        if (!empty($params['name'])) {
            $query->where('name', 'like', "%{$params['name']}%");
        }
        if (isset($params['type'])) {
            $query->where('type', $params['type']);
        }
        if (isset($params['status'])) {
            $query->where('status', $params['status']);
        }
        if (!empty($params['start_time'])) {
            $query->where('start_time', '>=', $params['start_time']);
        }
        if (!empty($params['end_time'])) {
            $query->where('end_time', '<=', $params['end_time']);
        }
        
        $coupons = $query->orderBy('id', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page);
            
        return json(['code' => 0, 'msg' => 'success', 'data' => $coupons]);
    }
    
    /**
     * @Apidoc\Title("获取优惠券详情")
     * @Apidoc\Method("GET")
     * @Apidoc\Url("/admin/coupon/detail/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="优惠券ID")
     */
    public function detail($id)
    {
        $coupon = CouponModel::find($id);
        
        if (!$coupon) {
            throw new BusinessException('优惠券不存在');
        }
        
        return json(['code' => 0, 'msg' => 'success', 'data' => $coupon]);
    }
    
    /**
     * @Apidoc\Title("创建优惠券")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/admin/coupon/store")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("name", type="string", require=true, desc="优惠券名称")
     * @Apidoc\Param("type", type="int", require=true, desc="优惠券类型：1满减券，2折扣券")
     * @Apidoc\Param("amount", type="number", require=true, desc="优惠金额/折扣率")
     * @Apidoc\Param("min_amount", type="number", require=true, desc="最低使用金额")
     * @Apidoc\Param("start_time", type="string", require=true, desc="开始时间")
     * @Apidoc\Param("end_time", type="string", require=true, desc="结束时间")
     * @Apidoc\Param("total", type="int", require=true, desc="发放总量")
     * @Apidoc\Param("per_limit", type="int", require=true, desc="每人限领数量")
     * @Apidoc\Param("use_type", type="int", require=true, desc="使用类型：0全场通用，1指定分类，2指定商品")
     * @Apidoc\Param("product_ids", type="array", desc="指定商品ID")
     * @Apidoc\Param("category_ids", type="array", desc="指定分类ID")
     * @Apidoc\Param("code", type="string", desc="优惠码")
     */
    public function store(Request $request)
    {
        $data = $request->post();
        
        try {
            // 验证数据
            $this->validateCouponData($data);
            
            // 创建优惠券
            $coupon = new CouponModel();
            $coupon->fill($data);
            $coupon->save();
            
            return json(['code' => 0, 'msg' => '创建成功', 'data' => $coupon]);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("更新优惠券")
     * @Apidoc\Method("PUT")
     * @Apidoc\Url("/admin/coupon/update/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="优惠券ID")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("name", type="string", desc="优惠券名称")
     * @Apidoc\Param("type", type="int", desc="优惠券类型：1满减券，2折扣券")
     * @Apidoc\Param("amount", type="number", desc="优惠金额/折扣率")
     * @Apidoc\Param("min_amount", type="number", desc="最低使用金额")
     * @Apidoc\Param("start_time", type="string", desc="开始时间")
     * @Apidoc\Param("end_time", type="string", desc="结束时间")
     * @Apidoc\Param("total", type="int", desc="发放总量")
     * @Apidoc\Param("per_limit", type="int", desc="每人限领数量")
     * @Apidoc\Param("use_type", type="int", desc="使用类型：0全场通用，1指定分类，2指定商品")
     * @Apidoc\Param("product_ids", type="array", desc="指定商品ID")
     * @Apidoc\Param("category_ids", type="array", desc="指定分类ID")
     * @Apidoc\Param("code", type="string", desc="优惠码")
     */
    public function update(Request $request, $id)
    {
        $data = $request->post();
        
        try {
            $coupon = CouponModel::find($id);
            
            if (!$coupon) {
                throw new BusinessException('优惠券不存在');
            }
            
            // 验证数据
            $this->validateCouponData($data, $coupon);
            
            // 更新优惠券
            $coupon->fill($data);
            $coupon->save();
            
            return json(['code' => 0, 'msg' => '更新成功', 'data' => $coupon]);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("删除优惠券")
     * @Apidoc\Method("DELETE")
     * @Apidoc\Url("/admin/coupon/destroy/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="优惠券ID")
     */
    public function destroy($id)
    {
        try {
            $coupon = CouponModel::find($id);
            
            if (!$coupon) {
                throw new BusinessException('优惠券不存在');
            }
            
            // 检查是否已被领取
            if (UserCouponModel::where('coupon_id', $id)->exists()) {
                throw new BusinessException('优惠券已被领取，无法删除');
            }
            
            $coupon->delete();
            
            return json(['code' => 0, 'msg' => '删除成功']);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("修改优惠券状态")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/admin/coupon/status/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="优惠券ID")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("status", type="int", require=true, desc="状态：0禁用，1启用")
     */
    public function status(Request $request, $id)
    {
        try {
            $coupon = CouponModel::find($id);
            
            if (!$coupon) {
                throw new BusinessException('优惠券不存在');
            }
            
            $status = $request->post('status');
            
            if (!in_array($status, [0, 1])) {
                throw new BusinessException('状态值不正确');
            }
            
            $coupon->status = $status;
            $coupon->save();
            
            return json(['code' => 0, 'msg' => '操作成功']);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("优惠券统计")
     * @Apidoc\Method("GET")
     * @Apidoc\Url("/admin/coupon/statistics")
     * @Apidoc\Param("start_time", type="string", desc="开始时间")
     * @Apidoc\Param("end_time", type="string", desc="结束时间")
     */
    public function statistics(Request $request)
    {
        $startTime = $request->get('start_time', date('Y-m-d'));
        $endTime = $request->get('end_time', date('Y-m-d'));
        
        // 优惠券总数
        $totalCount = CouponModel::whereBetween('created_at', [$startTime, $endTime])
            ->count();
            
        // 已领取数量
        $receivedCount = UserCouponModel::whereBetween('created_at', [$startTime, $endTime])
            ->count();
            
        // 已使用数量
        $usedCount = UserCouponModel::whereBetween('used_time', [$startTime, $endTime])
            ->where('status', 1)
            ->count();
            
        // 各类型优惠券数量
        $typeCount = CouponModel::whereBetween('created_at', [$startTime, $endTime])
            ->selectRaw('type, count(*) as count')
            ->groupBy('type')
            ->get()
            ->pluck('count', 'type')
            ->toArray();
            
        return json([
            'code' => 0,
            'msg' => 'success',
            'data' => [
                'total_count' => $totalCount,
                'received_count' => $receivedCount,
                'used_count' => $usedCount,
                'type_count' => $typeCount,
            ]
        ]);
    }
    
    /**
     * 验证优惠券数据
     */
    private function validateCouponData($data, $coupon = null)
    {
        if (empty($data['name'])) {
            throw new BusinessException('优惠券名称不能为空');
        }
        
        if (empty($data['type']) || !in_array($data['type'], [1, 2])) {
            throw new BusinessException('优惠券类型不正确');
        }
        
        if ($data['amount'] <= 0) {
            throw new BusinessException('优惠金额/折扣率必须大于0');
        }
        
        if ($data['type'] == 2 && $data['amount'] > 100) {
            throw new BusinessException('折扣率不能大于100');
        }
        
        if ($data['min_amount'] < 0) {
            throw new BusinessException('最低使用金额不能小于0');
        }
        
        if (empty($data['start_time'])) {
            throw new BusinessException('开始时间不能为空');
        }
        
        if (empty($data['end_time'])) {
            throw new BusinessException('结束时间不能为空');
        }
        
        if (strtotime($data['start_time']) >= strtotime($data['end_time'])) {
            throw new BusinessException('开始时间必须小于结束时间');
        }
        
        if ($data['total'] < 0) {
            throw new BusinessException('发放总量不能小于0');
        }
        
        if ($data['per_limit'] <= 0) {
            throw new BusinessException('每人限领数量必须大于0');
        }
        
        if (!in_array($data['use_type'], [0, 1, 2])) {
            throw new BusinessException('使用类型不正确');
        }
        
        if ($data['use_type'] == 1 && empty($data['category_ids'])) {
            throw new BusinessException('请选择指定分类');
        }
        
        if ($data['use_type'] == 2 && empty($data['product_ids'])) {
            throw new BusinessException('请选择指定商品');
        }
        
        if (!empty($data['code'])) {
            $exists = CouponModel::where('code', $data['code'])
                ->when($coupon, function ($query) use ($coupon) {
                    $query->where('id', '!=', $coupon->id);
                })
                ->exists();
                
            if ($exists) {
                throw new BusinessException('优惠码已存在');
            }
        }
    }
} 